package com.yc.cloud.wechat.service.impl;

import org.springframework.stereotype.Service;

import com.yc.cloud.basic.exception.Asserts;
import com.yc.cloud.wechat.dto.QRCodeDto;
import com.yc.cloud.wechat.dto.WxAccessTokenDto;
import com.yc.cloud.wechat.dto.WxUserInfoDto;
import com.yc.cloud.wechat.dto.resp.JSCode2SessionResp;
import com.yc.cloud.wechat.dto.resp.WxServiceAccessTokenErrorResp;
import com.yc.cloud.wechat.dto.resp.WxServicePhoneNumberResp;
import com.yc.cloud.wechat.service.WxService;
import com.yc.cloud.wechat.utils.WxMiniProgramUtils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.val;
import lombok.extern.slf4j.Slf4j;

/**
 * 小程序实现类
 */
@Service("wxMiniProgramServiceImpl")
@Slf4j
public class WxMiniProgramServiceImpl implements WxService {

    @Override
    public WxAccessTokenDto getAccessToken(String code, String appid, String appKey) {
        val result = WxMiniProgramUtils.getAccessToken(appid, appKey);
        if (StrUtil.isEmpty(result)) {
            log.error("wxMiniProgramServiceImpl getAccessToken result is null");
            return null;
        }
        if (result.contains("errcode")) {
            val accessTokenResp = JSONUtil.toBean(result, WxServiceAccessTokenErrorResp.class);
            Asserts.fail(accessTokenResp.getErrmsg());
        }

        val wxAccessTokenDto = JSONUtil.toBean(result, WxAccessTokenDto.class);
        if (wxAccessTokenDto == null) {
            return null;
        }
        // 小程序需要通过额外的方法获取openid
        val jsCode2SesionResult = WxMiniProgramUtils.jscode2session(code, appid, appKey);
        if (StrUtil.isEmpty(jsCode2SesionResult)) {
            return null;
        }
        val jsCode2SessionResp = JSONUtil.toBean(jsCode2SesionResult, JSCode2SessionResp.class);
        if (jsCode2SessionResp == null) {
            return null;
        }
        // 说明调用成功
        if (StrUtil.isEmpty(jsCode2SessionResp.getErrcode())) {
            wxAccessTokenDto.setOpenid(jsCode2SessionResp.getOpenid());
            wxAccessTokenDto.setUnionid(jsCode2SessionResp.getUnionid());
        }
        return wxAccessTokenDto;

    }

    @Override
    public String getOpenId(String code, String appid, String appKey) {
        val result = WxMiniProgramUtils.jscode2session(code, appid, appKey);
        if (StrUtil.isEmpty(result)) {
            val jsCode2SessionResp = JSONUtil.toBean(result, JSCode2SessionResp.class);
            if (StrUtil.isEmpty(jsCode2SessionResp.getErrcode())) {
                return jsCode2SessionResp.getOpenid();
            }
            log.error("getOpenId failed,msg=" + jsCode2SessionResp.getErrmsg());
        }
        return null;
    }

    @Override
    public WxUserInfoDto getUserInfo(String accessToken, String openId) {
        return null;
    }

    @Override
    public byte[] getQRCode(String accessToken, QRCodeDto qrCodeDto) {
        return WxMiniProgramUtils.getUnlimitedQRCode(accessToken, qrCodeDto);
    }

    @Override
    public String getPhoneNumber(String code, String accessToken) {
        val result = WxMiniProgramUtils.getPhoneNumber(code, accessToken);
        if (StrUtil.isNotEmpty(result)) {
            val phoneNumberResp = JSONUtil.toBean(result, WxServicePhoneNumberResp.class);
            if (phoneNumberResp.getErrcode() == 0) {
                return phoneNumberResp.getPhoneInfo().getPurePhoneNumber();
            }
            log.error("获取手机号失败，错误码：{}，错误信息：{}", phoneNumberResp.getErrcode(), phoneNumberResp.getErrmsg());
        }
        return null;
    }

}
